Namespace.Use("UI.Object", function(ns) {
    //
    //  Imports.
    //
    var Inherit = Namespace.Import("Base.Inherit");
    var Theme = Namespace.Import("UI.Theme");

    //
    //  Global.
    //
    var cst_InitialDefault = false;
    var cst_InitialFont = "bold 9pt Arial";

    var LabeledButton = Polymorphic.Create(
        [String, String],
        function(text, font) {
            //  Let parent class initialize.
            ns.CanvasButton.call(this, function() {});

            //
            //  Members.
            //
            var last_dft = !cst_InitialDefault;
            var dft = cst_InitialDefault;
            var last_text = null;
            var last_font = null;
            var out = this;

            //
            //  Private methods.
            //
            function RefreshRenderer(_text, _font, _dft) {
                out.AccessRenderer(function(_ctx, _state) {
                    var size = out.AccessSize();
                    Theme.Button.RenderLabeledButton.call(out, _ctx, size[0], size[1], _text, _font, _dft, _state);
                });
            }

            function Invalidate() {
                var refresh = false;
                if (last_dft != dft) {
                    last_dft = dft;
                    refresh = true;
                }
                if (last_text != text) {
                    last_text = text;
                    refresh = true;
                }
                if (last_font != font) {
                    last_font = font;
                    refresh = true;
                }
                if (refresh == true) {
                    RefreshRenderer(text, font, dft);
                }
            }

            //
            //  Public methods.
            //
            this.AccessText = Polymorphic.Create(
                [],
                function() {
                    return text;
                },
                [String],
                function(new_text) {
                    last_text = text;
                    text = new_text;
                    Invalidate();
                }
            );
            this.AccessDefault = Polymorphic.Create(
                [],
                function() {
                    return dft;
                },
                [Boolean],
                function(new_default) {
                    last_dft = dft;
                    dft = new_default;
                    Invalidate();
                }
            );
            this.AccessFont = Polymorphic.Create(
                [],
                function() {
                    return font;
                },
                [String],
                function(new_font) {
                    last_font = font;
                    font = new_font;
                    Invalidate();
                }
            );

            //  Invalidate immediately after created.
            Invalidate();
        },
        [String],
        function(text) {
            this.constructor.call(this, text, cst_InitialFont);
        }
    );

    //  Inherit "LabeledButton" from "CanvasButton".
    Inherit(LabeledButton, ns.CanvasButton);

    //  Export public APIs / classes.
    Namespace.Export(ns, "LabeledButton", LabeledButton);
});
